在 Spring Boot 中整合、使用 Redis

您所在的位置:网站首页 mac idea配置spring boot 在 Spring Boot 中整合、使用 Redis

在 Spring Boot 中整合、使用 Redis

2024-04-25 03:04| 来源: 网络整理| 查看: 265

Redis 是一款开源的,使用 C 开发的高性能内存 Key/Value 数据库,支持 String、Set、Hash、List、Stream 等等数据类型。它被广泛用于缓存、消息队列、实时分析、计数器和排行榜等场景。基本上是当代应用中必不可少的软件!

Spring Boot 对 Redis 提供了开箱即用的组件:spring-boot-starter-data-redis。通过这个 starter,我们只需要几行简单的配置就可以快速地在 Spring Boot 中整合、使用 Redis。

Spring Boot 整合 Redis Maven 依赖 org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2

除了 spring-boot-starter-data-redis 外,还添加了 commons-pool2 依赖,是因为我们需要使用到连接池。

配置属性

只需要在 application.yaml | properties 中配置如下常用的基本属性即可:

spring: data: redis: # 连接地址 host: "localhost" # 端口 port: 6379 # 数据库 database: 0 # 用户名,如果有 # username: # 密码,如果有 # password: # 连接超时 connect-timeout: 5s # 读超时 timeout: 5s # Lettuce 客户端的配置 lettuce: # 连接池配置 pool: # 最小空闲连接 min-idle: 0 # 最大空闲连接 max-idle: 8 # 最大活跃连接 max-active: 8 # 从连接池获取连接 最大超时时间,小于等于0则表示不会超时 max-wait: -1ms

注意,如果你使用的是 spring boot 2.x,上述配置的命名空间应该是 spring.redis 而不是 spring.data.redis。

更多完整的配置属性,请参阅 官方文档。

使用 Jedis 客户端

Spring Data Redis 默认使用 Lettuce 作为 Redis 客户端。官方还对 Jedis 提供了支持,你可以根据你的喜好进行选择。

要替换为 Jedis,首先需要从 spring-boot-starter-data-redis 排除 lettuce ,并且添加 jedis 依赖:

org.springframework.boot spring-boot-starter-data-redis io.lettuce lettuce-core redis.clients jedis org.apache.commons commons-pool2

然后修改配置文件,把 lettuce 配置替换为 jedis 配置即可:

spring.data.redis.jedis.pool.enabled=true spring.data.redis.jedis.pool.max-active=8 spring.data.redis.jedis.pool.max-idle=8 spring.data.redis.jedis.pool.max-wait=-1ms spring.data.redis.jedis.pool.min-idle=0 spring.data.redis.jedis.pool.time-between-eviction-runs=

得益于 Spring Data Redis 提供的抽象、封装。在修改了底层客户端后,我们基本上不用修改任何业务代码。

推荐在项目中使用 lettuce 客户端,因为它是基于 Netty 开发,支持非阻塞式 IO,性能会更好。

使用 StringRedisTemplate

配置就绪后,StringRedisTemplate 已经可用,你可以在任何地方注入、使用:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class); // 注入 StringRedisTemplate @Autowired StringRedisTemplate stringRedisTemplate; @Test public void test() { // 设置 this.stringRedisTemplate.opsForValue().set("title", "spring 中文网", Duration.ofMinutes(5)); // 读取 String val = this.stringRedisTemplate.opsForValue().get("title"); logger.info("value={}", val); } }

对于 StringRedisTemplate 更完整的方法列表,你可以参阅其 java doc。

自定义 RedisTemplate

如果基本的 StringRedisTemplate 不能满足你的需求,你也可以自定义 RedisTemplate 实现。

例如,我们想要自定义一个 JsonRedisTemplate,用于把任意 Java 对象序列化为 json 数据存储到 Redis,并且也能够把 Redis 中的 json 数据反序列化为任意 Java 对象。

如下:

import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; @Component public class JsonRedisTemplate extends RedisTemplate{ public JsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) { // 构造函数注入 RedisConnectionFactory,设置到父类 super.setConnectionFactory(redisConnectionFactory); // 使用 Jackson 提供的通用 Serializer GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(); serializer.configure(mapper -> { // 如果涉及到对 java.time 类型的序列化,反序列化那么需要注册 JavaTimeModule mapper.registerModule(new JavaTimeModule()); }); // String 类型的 key/value 序列化 super.setKeySerializer(StringRedisSerializer.UTF_8); super.setValueSerializer(serializer); // Hash 类型的 key/value 序列化 super.setHashKeySerializer(StringRedisSerializer.UTF_8); super.setHashValueSerializer(serializer); } }

首先,继承 RedisTemplate,泛型 K 表示 Redis Key 类型,一般都是 String,泛型 V 表示 Redis Value 类型,既然我们需要的是一个通用的 JSON Template,所以设置为 Object,Value 值可以是任意对象。

在构造函数中注入 RedisConnectionFactory 设置到父类,这是必须的。

然后创建GenericJackson2JsonRedisSerializer 实例,它是基于 Jackson 的 RedisSerializer 实现,用于任意 Java 对象和 JSON 字符串之间的序列化/反序列化。使用该实例作为普通 Value 和 Hash Value 的序列化/反序列化器。注意,因为序列化的对象可能包含了 java.time 类型的日期字段,如:LocalTime、LocalDate 以及 LocalDateTime,所以需要注册 JavaTimeModule。

创建测试类进行测试。如下:

package cn.springdoc.demo.test; import java.time.Duration; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import cn.springdoc.demo.redis.JsonRedisTemplate; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class DemoApplicationTests { static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class); // 注入 JsonRedisTemplate @Autowired JsonRedisTemplate jsonRedisTemplate; @SuppressWarnings("unchecked") @Test public void test() { // Map Map map = new HashMap(); map.put("title", "spring 中文网"); map.put("url", "https://springdoc.cn"); map.put("createAt", LocalDateTime.now()); // 设置 key/value this.jsonRedisTemplate.opsForValue().set("key1-string", map, Duration.ofMinutes(5)); // 读取 key/value map = (Map) this.jsonRedisTemplate.opsForValue().get("key1-string"); logger.info("map={}", map); // 设置 Hash Value this.jsonRedisTemplate.opsForHash().put("key2-hash", "app", map); // 读取 Hash Value map = (Map) this.jsonRedisTemplate.opsForHash().get("key2-hash", "app"); logger.info("map={}", map); } }

我们创建了一个 Map 对象,存储了 2 个 String 和一个 LocalDateTime 字段。然后使用 JsonRedisTemplate 把它存储为普通 Value 和 Hash Value。

存储成功后,再进行读取,反序列化为原来的 Map 对象。

运行测试,执行日志如下:

[ main] c.s.demo.test.DemoApplicationTests : map={title=spring 中文网, url=https://springdoc.cn, createAt=2023-09-25T10:53:44.618386900} [ main] c.s.demo.test.DemoApplicationTests : map={title=spring 中文网, url=https://springdoc.cn, createAt=2023-09-25T10:53:44.618386900}

如你所见,序列化为 JSON、反序列化为对象都没问题。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3